#ifndef __WHIMSY_DATATYPE_BASE_HPP__SHANHAOBO_19800429__
#define __WHIMSY_DATATYPE_BASE_HPP__SHANHAOBO_19800429__

#include "./WhimsyConfig.hpp"

namespace Whms
{
    ///==============================================================///

    namespace Int8
    {
        WIZ_DECLARE(::Wiz::Int8::Type);
    } /// end of namespace Int8

    namespace Int16
    {
        WIZ_DECLARE(::Wiz::Int16::Type);
    } /// end of namespace Int16

    namespace Int32
    {
        WIZ_DECLARE(::Wiz::Int32::Type);
    } /// end of namespace Int32

    namespace Int64
    {
        WIZ_DECLARE(::Wiz::Int64::Type);
    } /// end of namespace Int64

    namespace UInt8
    {
        WIZ_DECLARE(::Wiz::UInt8::Type);
    } /// end of namespace UInt8

    namespace UInt16
    {
        WIZ_DECLARE(::Wiz::UInt16::Type);
    } /// end of namespace UInt16

    namespace UInt32
    {
        WIZ_DECLARE(::Wiz::UInt32::Type);
    } /// end of namespace UInt

    namespace UInt64
    {
        WIZ_DECLARE(::Wiz::UInt64::Type);
    } /// end of namespace UInt64

    namespace Real32
    {
        WIZ_DECLARE(::Wiz::Real32::Type);
    } /// end of namespace Real32

    namespace Real64
    {
        WIZ_DECLARE(::Wiz::Real64::Type);
    } /// end of namespace Real64
    ///==============================================================///

    namespace Byte
    {
        WIZ_DECLARE(::Wiz::Byte::Type);
    } /// end of namespace Byte

    namespace Real
    {
        WIZ_DECLARE_HELPER_REAL32(::Whms::Real);
    } /// end of namespace Real

    namespace Int
    {
        WIZ_DECLARE(::Wiz::Int32::Type);
        static const ::Whms::Int::Type Min = ::Wiz::GetMin<::Whms::Int::Type>();
        static const ::Whms::Int::Type Max = ::Wiz::GetMax<::Whms::Int::Type>();
    } /// end of namespace Int

    namespace UInt
    {
        WIZ_DECLARE(::Wiz::UInt32::Type);
        static const ::Whms::UInt::Type Min = ::Wiz::GetMin<::Whms::UInt::Type>();
        static const ::Whms::UInt::Type Max = ::Wiz::GetMax<::Whms::UInt::Type>();
    } /// end of namespace UInt

    ///==============================================================///
    namespace Index
    {
        WIZ_DECLARE(::Wiz::Int32::Type);
    } /// end of namespace Index

    namespace Index16
    {
        WIZ_DECLARE(::Wiz::Int16::Type);
    } /// end of namespace Index16

    namespace Index32
    {
        WIZ_DECLARE(::Wiz::Int32::Type);
    } /// end of namespace Index32

    namespace Index64
    {
        WIZ_DECLARE(::Wiz::Int64::Type);
    } /// end of namespace Index64
    ///==============================================================///

    namespace Bool
    {
        WIZ_DECLARE(::Wiz::Bool::Type);
        static const ::Whms::Bool::Type True  = ::Wiz::Bool::True;
        static const ::Whms::Bool::Type False = ::Wiz::Bool::False;
    } /// end of namespace Bool

    namespace Boolean
    {
        WIZ_DECLARE(::Wiz::Boolean::Type<::Whms::UInt::Type>);
        static const ::Whms::Bool::Type True  = ::Wiz::Bool::True;
        static const ::Whms::Bool::Type False = ::Wiz::Bool::False;
    } /// end of namespace Boolean

    namespace Void
    {
        typedef ::Wiz::Void::Type Type;
        WIZ_DECLARE_PTR(::Whms::Void::Type);
    } /// end of namespace Void

    namespace Size
    {
        WIZ_DECLARE(::Wiz::Size::Type);
    } /// end of namespace Size

    namespace Size16
    {
        WIZ_DECLARE(::Wiz::Size16::Type);
    } /// end of namespace Size16
    ///==============================================================///

    namespace String
    {
        struct Type : public ::Wiz::WString::Type
        {
            typedef ::Wiz::WString::Type tSuper;
        public:
            Type() : tSuper()
            {
            }
            Type(const tChar* _Ptr) : tSuper( _Ptr )
            {
            }

            Type(const tSuper& _Right) : tSuper( _Right )
            {
            }

            Type(const tThis& _Right, tSize _Roff, tSize _Count = npos) : tSuper( _Right, _Roff, _Count )
            {
            }

            Type(const tChar* _Ptr, tSize _Count) : tSuper( _Ptr, _Count )
            {
            }
        public:

            ::Whms::Void::Type From(::Wiz::String::In InStr)
            {
				::Wiz::MultiBytesStrToWCharStr(*this, InStr, "");
            }

            ::Whms::Void::Type From(::Wiz::Char::InPtr InCharPtr, ::Wiz::Size::In CharSZ)
            {
				::Wiz::String::Type NewStr(InCharPtr, CharSZ);
				From(NewStr);
            }

            ::Whms::Void::Type To(::Wiz::String::Out Str) const
            {
				::Wiz::WCharStrToMultiBytesStr(Str, *this, "");
            }
        };
        WIZ_DECLARE(::Whms::String::Type);
    } /// end of namespace String

    namespace Char
    {
        WIZ_DECLARE(::Wiz::WString::Char::Type);
    } /// end of namespace Char

    ///==============================================================///

    namespace Name
    {
        namespace Proxy
        {
            struct Type : public ::Wiz::Name::Proxy::Type<::Whms::Name::Proxy::Type, ::Whms::String::Type, ::Whms::Index::Type>
            {
                static ::Whms::Index::Type CalcHashCodeImpl(tStringFixedConstCharPtr InStr)
                {
                    return ::Wiz::StringHash::SDBM::Calc(InStr);
                }
            };
        } /// end of namespace Proxy

        typedef ::Wiz::Name::Type<::Whms::Name::Proxy::Type, 65536, 1024> Type;
        WIZ_DECLARE(::Whms::Name::Type);
    } /// end of namespace Name
    ///==============================================================///
    namespace Vec2
    {
        struct Type : public ::Wiz::Vector2::Type<::Whms::Real::Type>
        {
            typedef ::Wiz::Vector2::Type<::Whms::Real::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY) : tSuper(InX, InY)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}

            ::Whms::Bool::Type IsNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                tMethod::IsNearlyZero(*this, InTolerance);
            }

            ::Whms::Bool::Type NotNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                return IsNearlyZero(InTolerance) == ::Whms::Bool::False;
            }
        };
        WIZ_DECLARE(::Whms::Vec2::Type);
        typedef WIZ_ALIGN_16(::Whms::Vec2::Type)  AlignedType;


        WIZ_INLINE ::Whms::Real::Type Dot(::Whms::Vec2::In InVec1, ::Whms::Vec2::Type InVec2)
        {
            return ::Whms::Vec2::Type::Dot(InVec1, InVec2);
        }
    } /// end of namespace Vector2
    namespace Vec3
    {
        struct Type : public ::Wiz::Vector3::Type<::Whms::Real::Type>
        {
            typedef ::Wiz::Vector3::Type<::Whms::Real::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY, const tElement& InZ) : tSuper(InX, InY, InZ)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}

            ::Whms::Bool::Type IsNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                return tMethod::IsNearlyZero(*this, InTolerance);
            }

            ::Whms::Bool::Type NotNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                return IsNearlyZero(InTolerance) == ::Whms::Bool::False;
            }
        };
        WIZ_DECLARE(::Whms::Vec3::Type);
        typedef WIZ_ALIGN_16(::Whms::Vec3::Type)  AlignedType;

        WIZ_INLINE ::Whms::Real::Type Dot(::Whms::Vec3::In InVec1, ::Whms::Vec3::Type InVec2)
        {
            return ::Whms::Vec3::Type::Dot(InVec1, InVec2);
        }
        WIZ_INLINE ::Whms::Vec3::Type Cross(::Whms::Vec3::In InVec1, ::Whms::Vec3::Type InVec2)
        {
            return ::Whms::Vec3::Type::Cross(InVec1, InVec2);
        }
    } /// end of namespace Vector3
    namespace Vec4
    {
        struct Type : public ::Wiz::Vector4::Type<::Whms::Real::Type>
        {
            typedef ::Wiz::Vector4::Type<::Whms::Real::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY, const tElement& InZ, const tElement& InW) : tSuper(InX, InY, InZ, InW)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}

            ::Whms::Bool::Type IsNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                tMethod::IsNearlyZero(*this, InTolerance);
            }

            ::Whms::Bool::Type NotNearlyZero(const tElement& InTolerance = ::Whms::Real::Epsilon) const
            {
                return IsNearlyZero(InTolerance) == ::Whms::Bool::False;
            }
        };
        WIZ_DECLARE(::Whms::Vec4::Type);
        typedef WIZ_ALIGN_16(::Whms::Vec4::Type)  AlignedType;

        WIZ_INLINE ::Whms::Real::Type Dot(::Whms::Vec4::In InVec1, ::Whms::Vec4::Type InVec2)
        {
            return ::Whms::Vec4::Type::Dot(InVec1, InVec2);
        }
    } /// end of namespace Vector4
    ///==============================================================///
    namespace IntVec2
    {
        struct Type : public ::Wiz::Vector2::Type<::Whms::Int::Type>
        {
            typedef ::Wiz::Vector2::Type<::Whms::Int::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY) : tSuper(InX, InY)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}
        };
        WIZ_DECLARE(::Whms::IntVec2::Type);

        typedef WIZ_ALIGN_16(::Whms::IntVec2::Type)  AlignedType;
    } /// end of namespace IntVec2
    namespace IntVec3
    {
        struct Type : public ::Wiz::Vector3::Type<::Whms::Int::Type>
        {
            typedef ::Wiz::Vector3::Type<::Whms::Int::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY, const tElement& InZ) : tSuper(InX, InY, InZ)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}
        };
        WIZ_DECLARE(::Whms::IntVec3::Type);
        typedef WIZ_ALIGN_16(::Whms::IntVec3::Type)  AlignedType;
    } /// end of namespace IntVec3
    namespace IntVec4
    {
        struct Type : public ::Wiz::Vector4::Type<::Whms::Int::Type>
        {
            typedef ::Wiz::Vector4::Type<::Whms::Int::Type> tSuper;
            Type()
            {}
            Type(const tElement& InX, const tElement& InY, const tElement& InZ, const tElement& InW) : tSuper(InX, InY, InZ, InW)
            {}
            Type(const tElement& InEle) : tSuper(InEle)
            {}
            Type(const tSuper& InOther) : tSuper(InOther)
            {}
        };
        WIZ_DECLARE(::Whms::IntVec4::Type);
        typedef WIZ_ALIGN_16(::Whms::IntVec4::Type)  AlignedType;
    } /// end of namespace IntVec4
    ///==============================================================///
    namespace Mat22
    {
#if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        WIZ_DECLARE(::Wiz::Matrix22::RowMajor::Type<::Whms::Real::Type>);
#elif (WHIMSY_MAT_MAJOR == WHIMSY_MAT_COLMAJOR)
        WIZ_DECLARE(::Wiz::Matrix22::ColMajor::Type<::Whms::Real::Type>);
#else
#error  Illegal Matrix Major
#endif /// #if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        typedef WIZ_ALIGN_16(::Whms::Mat22::Type)  AlignedType;
    } /// end of namespace Mat22
    namespace Mat33
    {
#if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        WIZ_DECLARE(::Wiz::Matrix33::RowMajor::Type<::Whms::Real::Type>);
#elif (WHIMSY_MAT_MAJOR == WHIMSY_MAT_COLMAJOR)
        WIZ_DECLARE(::Wiz::Matrix33::ColMajor::Type<::Whms::Real::Type>);
#else
#error  Illegal Matrix Major
#endif /// #if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        typedef WIZ_ALIGN_16(::Whms::Mat33::Type)  AlignedType;
    } /// end of namespace Mat33
    namespace Mat43
    {
#if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        WIZ_DECLARE(::Wiz::Matrix43::RowMajor::Type<::Whms::Real::Type>);
#elif (WHIMSY_MAT_MAJOR == WHIMSY_MAT_COLMAJOR)
        WIZ_DECLARE(::Wiz::Matrix43::ColMajor::Type<::Whms::Real::Type>);
#else
#error  Illegal Matrix Major
#endif /// #if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        typedef WIZ_ALIGN_16(::Whms::Mat43::Type)  AlignedType;
    } /// end of namespace Mat43
    namespace Mat44
    {
#if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        WIZ_DECLARE(::Wiz::Matrix44::RowMajor::Type<::Whms::Real::Type>);
#elif (WHIMSY_MAT_MAJOR == WHIMSY_MAT_COLMAJOR)
        WIZ_DECLARE(::Wiz::Matrix44::ColMajor::Type<::Whms::Real::Type>);
#else
#error  Illegal Matrix Major
#endif /// #if (WHIMSY_MAT_MAJOR == WHIMSY_MAT_ROWMAJOR)
        typedef WIZ_ALIGN_16(::Whms::Mat44::Type)  AlignedType;
    } /// end of namespace Mat44
    ///==============================================================///
    namespace Quat
    {
        WIZ_DECLARE(::Wiz::Quat::Type<::Whms::Real::Type>);
    } /// end of namespace Quat
    ///==============================================================///
    namespace EulerAngles
    {
        namespace XYZ
        {
            WIZ_DECLARE(::Wiz::EulerAngles::XYZ::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::XYZ::Type)  AlignedType;
        } /// end of namespace XYZ

        namespace XZY
        {
            WIZ_DECLARE(::Wiz::EulerAngles::XZY::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::XZY::Type)  AlignedType;
        } /// end of namespace XZY

        namespace YXZ
        {
            WIZ_DECLARE(::Wiz::EulerAngles::YXZ::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::YXZ::Type)  AlignedType;
        } /// end of namespace YXZ

        namespace YZX
        {
            WIZ_DECLARE(::Wiz::EulerAngles::YZX::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::YZX::Type)  AlignedType;
        } /// end of namespace YZX

        namespace ZXY
        {
            WIZ_DECLARE(::Wiz::EulerAngles::ZXY::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::ZXY::Type)  AlignedType;
        } /// end of namespace ZXY

        namespace ZYX
        {
            WIZ_DECLARE(::Wiz::EulerAngles::ZYX::Type<::Whms::Real::Type>);
            typedef WIZ_ALIGN_16(::Whms::EulerAngles::ZYX::Type)  AlignedType;
        } /// end of namespace ZYX

#if (WHIMSY_EULER_ORDER == WHIMSY_EULER_XYZ)
        WIZ_DECLARE(::Whms::EulerAngles::XYZ::Type);
#elif (WHIMSY_EULER_ORDER == WHIMSY_EULER_XZY)
        WIZ_DECLARE(::Whms::EulerAngles::XZY::Type);
#elif (WHIMSY_EULER_ORDER == WHIMSY_EULER_YXZ)
        WIZ_DECLARE(::Whms::EulerAngles::YXZ::Type);
#elif (WHIMSY_EULER_ORDER == WHIMSY_EULER_YZX)
        WIZ_DECLARE(::Whms::EulerAngles::YZX::Type);
#elif (WHIMSY_EULER_ORDER == WHIMSY_EULER_ZXY)
        WIZ_DECLARE(::Whms::EulerAngles::ZXY::Type);
#elif (WHIMSY_EULER_ORDER == WHIMSY_EULER_ZYX)
        WIZ_DECLARE(::Whms::EulerAngles::ZYX::Type);
#else
#error  Illegal Euler Order
#endif
        typedef WIZ_ALIGN_16(::Whms::EulerAngles::Type)  AlignedType;
    } /// end of namespace EulerAngles
    ///==============================================================///
    namespace Rect
    {
        WIZ_DECLARE(::Wiz::Rect::Type<::Whms::Real::Type>);
    } /// end of namespace Rect
    namespace URect
    {
        WIZ_DECLARE(::Wiz::Rect::Type<::Whms::UInt::Type>);
    } /// end of namespace URect
    namespace IRect
    {
        WIZ_DECLARE(::Wiz::Rect::Type<::Whms::Int::Type>);
    } /// end of namespace IRect
	///==============================================================///
    namespace Box
    {
        struct Type : ::Wiz::Box::Type<::Whms::Real::Type>
        {
            Type()
            {
            }
        public:
            ::Whms::Void::Type SetNull()
            {
                this->m_Min.Set(::Wiz::Real::Max, ::Wiz::Real::Max, ::Wiz::Real::Max);
                this->m_Max.Set(::Wiz::Real::Min, ::Wiz::Real::Min, ::Wiz::Real::Min);
            }

            ::Whms::Void::Type SetInfinite()
            {
                this->m_Max.Set(::Wiz::Real::Max, ::Wiz::Real::Max, ::Wiz::Real::Max);
                this->m_Min.Set(::Wiz::Real::Min, ::Wiz::Real::Min, ::Wiz::Real::Min);
            }
        public:
        };
        WIZ_DECLARE(::Whms::Box::Type);
	} /// end of namespace Box
    ///==============================================================///
    namespace Buffer2D
    {
        template<class T>
        struct Type : public ::Wiz::Buffer2D::Type<T, 16, 16, ::Wiz::USize32::Type, ::Wiz::Null::Type>
        {

        };
    }
    ///==============================================================///
} /// end of namespace Whms

#endif /*__WHIMSY_DATATYPE_BASE_HPP__SHANHAOBO_19800429__*/
